package com.sunwayhorizo.health.business.patad.empi.query;

import com.sunwayhorizo.health.business.base.query.*;
import com.sunwayhorizo.health.common.StrUtil;
import com.sunwayhorizo.health.hl7.common.*;
import java.util.*;
import javax.ejb.*;
import javax.persistence.*;
import org.jboss.seam.annotations.*;
import org.jboss.seam.log.Log;
import com.sunwayhorizo.health.hl7.rim.*;
import com.sunwayhorizo.health.hl7.rim.Role;
import com.sunwayhorizo.health.hl7.vocabulary.*;
import static com.sunwayhorizo.health.hl7.vocabulary.RoleIICode.*;

@Name("PatientQuery")
@Stateless
public class PatientQuery extends BaseQuery implements PatientQueryLocal
{

    private Map<String, Map<String, Object>> conditions = new HashMap<String, Map<String, Object>>();


    @Override
    public Role findFamilyRole(String roleId)
    {
        StringBuilder jpql = new StringBuilder();
        jpql.append("select r from Role r left join r.rolePrtcptnsList part left join part.participationAct act");
        jpql.append(" left join act.prtcptnsActList part2 ");
        jpql.append(" left join part2.roleParticipation role1 ");
        jpql.append(" where r.codeEtsId=");
        jpql.append(convertInJpql(RoleCode.FAMILY.code().stringValue()));
        jpql.append(" and role1.roleId=");
        jpql.append(roleId);
        @SuppressWarnings("unchecked")
        List<Role> roles = em.createQuery(jpql.toString()).getResultList();
        if (!roles.isEmpty())
        {
            return roles.get(0);
        }
        else
        {
            return null;
        }

    }


    // 根据患者id(或者医保号)，姓名，证件号,地址查询患者人数
    @Override
    public long findCountPatientByConditions(String id, String patName, String certificate, String address) throws Hl7Exception
    {
        conditions.clear();
        if (StrUtil.isNotEmpty(id))
        {
            Map<String, Object> rii = new HashMap<String, Object>();

            rii.put("extensionTxt", id);
            conditions.put("rii", rii);
        }

        if (StrUtil.isNotEmpty(patName))
        {
            Map<String, Object> pe = new HashMap<String, Object>();
            conditions.put("pe", pe);

            Map<String, Object> en = new HashMap<String, Object>();
            en.put("formatted", patName);
            conditions.put("en", en);
        }

        if (StrUtil.isNotEmpty(certificate))

        {
            Map<String, Object> pe = new HashMap<String, Object>();
            conditions.put("pe", pe);

            Map<String, Object> eii = new HashMap<String, Object>();
            eii.put("extensionTxt", certificate);
            conditions.put("eii", eii);

        }
        if (StrUtil.isNotEmpty(address))
        {
            Map<String, Object> pe = new HashMap<String, Object>();
            conditions.put("pe", pe);
            Map<String, Object> addr = new HashMap<String, Object>();
            addr.put("formatted", address);
            conditions.put("addr", addr);
        }
        return baseCountPatientQuery(conditions);

    }


    // 根据患者id(或者医保号)，姓名，证件号,地址查询患者
    @Override
    public List<Patient> findPatientByConditions(String id, String patName, String certificate, String address, int pageSize, int pageNo)
        throws Hl7Exception
    {
        conditions.clear();
        if (StrUtil.isNotEmpty(id))
        {
            Map<String, Object> rii = new HashMap<String, Object>();

            rii.put("extensionTxt", id);
            conditions.put("rii", rii);
        }

        if (StrUtil.isNotEmpty(patName))
        {
            Map<String, Object> pe = new HashMap<String, Object>();
            conditions.put("pe", pe);

            Map<String, Object> en = new HashMap<String, Object>();
            en.put("formatted", patName);
            conditions.put("en", en);
        }

        if (StrUtil.isNotEmpty(certificate))

        {
            Map<String, Object> pe = new HashMap<String, Object>();
            conditions.put("pe", pe);

            Map<String, Object> eii = new HashMap<String, Object>();
            eii.put("extensionTxt", certificate);
            conditions.put("eii", eii);
        }
        if (StrUtil.isNotEmpty(address))
        {
            Map<String, Object> pe = new HashMap<String, Object>();
            conditions.put("pe", pe);

            Map<String, Object> addr = new HashMap<String, Object>();
            addr.put("formatted", address);
            conditions.put("addr", addr);
        }
        return basePatientQuery(conditions, pageSize, pageNo);
    }


    // 患者主索引id查询患者
    @Override
    public Patient findPatientByNeturalId(String id) throws Hl7Exception
    {
        
        if (id == null || id.trim().equals(""))
        {
            return null;
        }

        conditions.clear();

        Map<String, Object> rii = new HashMap<String, Object>();
        rii.put("identifierName", PATIENTID.toString());
        rii.put("extensionTxt", id);
        conditions.put("rii", rii);

        List<Patient> patients = basePatientQuery(conditions, 1, 1);
        if (!patients.isEmpty())
        {
            return patients.get(0);
        }
        else
        {
            log.info("PatientQuery-findPatientByNeturalId-id为" + id + "patient为空！ :");
            return null;
        }

    }


    // 患者就诊卡号查询患者
    @Override
    public Patient findPatientByMedicalCardId(String medicalCardId) throws Hl7Exception
    {
        if (medicalCardId == null || medicalCardId.trim().equals(""))
        {
            return null;
        }

        conditions.clear();
        Map<String, Object> rii = new HashMap<String, Object>();
        rii.put("identifierName", MEDICALCARD.toString());
        rii.put("extensionTxt", medicalCardId);
        conditions.put("rii", rii);

        List<Patient> patients = basePatientQuery(conditions, 1, 1);
        if (!patients.isEmpty())
        {
            return patients.get(0);
        }
        else
        {
            log.info("PatientQuery-findPatientByMedicalCardId-medicalCardId为" + medicalCardId + "patient为空！ :");
            return null;
        }
    }


    // 根据科室entityId查询当前在科患者
    @Override
    public List<Patient> findPateintsIndepartment(long workgroupId, int pageNo, int pageSize) throws Hl7Exception
    {

        conditions.clear();

        Map<String, Object> act = new HashMap<String, Object>();
        act.put("codeEtsId", ActCode.INDEPARTMENT.code().stringValue());
        act.put("statusCode", ActStatus.ACTIVE.code().stringValue());
        conditions.put("act", act);

        Map<String, Object> role1 = new HashMap<String, Object>();
        conditions.put("role1", role1);

        Map<String, Object> se1 = new HashMap<String, Object>();
        se1.put("entityId", workgroupId);
        conditions.put("se1", se1);

        List<Patient> patients = basePatientQuery(conditions, 0, 0);
        return patients;
    }


    public EntityManager getEm()
    {
        return em;
    }


    public void setEm(EntityManager em)
    {
        this.em = em;
    }


    public Log getLog()
    {
        return log;
    }


    public void setLog(Log log)
    {
        this.log = log;
    }


    @Override
    public <T> List<T> getObjects(Class<T> clazz, Map<String, Object> conditions) throws Hl7Exception
    {
        return super.getObjects(clazz, conditions);
    }


    private String getBasePatientQueryJpql(Map<String, Map<String, Object>> conditions, Class<?> clazz)
    {
        StringBuilder jpql1 = new StringBuilder();
        if (clazz != null && clazz.equals(Long.class))
        {
            jpql1.append("select count(distinct pat.roleId) from Patient pat ");
        }
        else
        {
            jpql1.append("select distinct pat from Patient pat ");
        }
        StringBuilder jpql2 = new StringBuilder();
        jpql2.append(" where 1=1 ");

        // 患者roleii
        if (conditions.get("rii") != null)
        {
            jpql1.append(" left join pat.roleIiList rii ");

            if (conditions.get("rii").get("identifierName") != null)
            {
                jpql2.append(" and rii.identifierName=");
                jpql2.append(convertInJpql(conditions.get("rii").get("identifierName")));
            }
            if (conditions.get("rii").get("extensionTxt") != null)
            {
                jpql2.append(" and rii.extensionTxt=");
                jpql2.append(convertInJpql(conditions.get("rii").get("extensionTxt")));
            }

        }

        // 所参与的动作
        if (conditions.get("act") != null)
        {
            jpql1.append(" left join pat.rolePrtcptnsList part1 ");
            jpql1.append(" left join part1.participationAct act ");

            if (conditions.get("act").get("codeEtsId") != null)
            {
                jpql2.append(" and act.codeEtsId=");
                jpql2.append(convertInJpql(conditions.get("act").get("codeEtsId")));
            }
            if (conditions.get("act").get("statusCode") != null)
            {
                jpql2.append(" and act.statusCode=");
                jpql2.append(convertInJpql(conditions.get("act").get("statusCode")));
            }
        }

        // 所参与的动作的其他参与角色
        if (conditions.get("act") != null && conditions.get("role1") != null)
        {
            jpql1.append(" left join act.prtcptnsActList part2 ");
            jpql1.append(" left join part2.roleParticipation role1 ");
        }

        // 所参与的动作的其他参与角色的范围实体
        if (conditions.get("act") != null && conditions.get("role1") != null && conditions.get("se1") != null)
        {

            jpql1.append(" left join role1.scoperEntities se1 ");
            jpql2.append(" and se1.entityId=");
            jpql2.append(convertInJpql(conditions.get("se1").get("entityId")));
        }

        // 扮演患者的实体
        if (conditions.get("pe") != null)
        {
            jpql1.append(" left join pat.playerEntities pe ");
        }

        // 扮演患者的实体名称
        if (conditions.get("pe") != null && conditions.get("en") != null)
        {
            jpql1.append(" left join pe.entyNamesList en ");

            if (conditions.get("en").get("formatted") != null)
            {
                jpql2.append(" and en.formatted like ");
                jpql2.append(convertInJpql(conditions.get("en").get("formatted") + "%"));
            }
        }

        // 扮演患者的实体的entityII
        if (conditions.get("pe") != null && conditions.get("eii") != null)
        {
            jpql1.append(" left join pe.entyIiList eii ");
            if (conditions.get("eii").get("extensionTxt") != null)
            {
                jpql2.append(" and eii.extensionTxt=");
                jpql2.append(convertInJpql(conditions.get("eii").get("extensionTxt")));
            }
        }
        // 扮演患者的实体的地址
        if (conditions.get("pe") != null && conditions.get("addr") != null)
        {
            jpql1.append(" left join pe.entyAddrsList addr ");
            if (conditions.get("addr").get("formatted") != null)
            {
                jpql2.append(" and addr.formatted like ");
                jpql2.append(convertInJpql(conditions.get("addr").get("formatted") + "%"));
            }
        }
        String jpql=jpql1.append(jpql2).toString();
        log.info("查询语句为:"+jpql);
        return jpql;
    }


    @Override
    public List<Patient> basePatientQuery(Map<String, Map<String, Object>> conditions, int pageSize, int pageNo) throws Hl7Exception
    {
        Query query = em.createQuery(getBasePatientQueryJpql(conditions, null));
        if (pageNo > 0 && pageSize > 0)
        {
            query.setFirstResult((pageNo - 1) * pageSize).setMaxResults(pageSize);
        }
        @SuppressWarnings("unchecked")
        List<Patient> encounters = query.getResultList();
        return encounters;
    }


    @Override
    public long baseCountPatientQuery(Map<String, Map<String, Object>> conditions) throws Hl7Exception
    {
        Query query = em.createQuery(getBasePatientQueryJpql(conditions, Long.class));
        Long count = (Long) query.getSingleResult();
        return count;
    }

}
